package ec.edu.ups.cidi.siia.plamdep.utils;
import java.awt.Container;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.itextpdf.awt.geom.Rectangle;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.Base64.InputStream;
import com.itextpdf.text.pdf.codec.Base64.OutputStream;

import ec.edu.ups.cidi.siia.plamdep.configuracion.ConfiguracionGlobal;
import ec.edu.ups.cidi.siia.plamdep.modelo.reporte.ReporteCabecera;
import ec.edu.ups.cidi.siia.plamdep.modelo.reporte.ReporteData;
import ec.edu.ups.cidi.siia.plamdep.modelo.reporte.ReporteDetalle;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JasperViewer;

public class ReportesManager {

	private static String reporteResumen=ConfiguracionGlobal.pathResources+"/reports_templates/jasper/" +"reporte-analisis.jasper";
	/**
	 * Genera un reporte para una ventana swing
	 * @param rc
	 * @param detalleList
	 * @return
	 */
	
	
	
	public static Container getReporteContainer(  ReporteData datos)
    {
		
		List<ReporteDetalle>detAux=new ArrayList<ReporteDetalle>();
		detAux.add(new ReporteDetalle());
		ReporteCabecera rc=datos.getCabecera();
		
		try{
			return generarPDFContainer(reporteResumen,getCabeceraParams(datos),detAux);
		}catch(Exception e)
		{
			Log.log(e, Log.MOD_UTILS, Log.LEVEL_ERROR, ReportesManager.class, "Error al generar reporte...");
			return null;
		}
    }
    /**
     * Genera un reporte y lo almacena, retorna la ruta donde fue almacenado
     * @param rc
     * @param detalleList
     * @return
     */
	public static String getReportePath(  ReporteData datos)
    {
		
		List<ReporteDetalle>detalleList=datos.getDetallesComparador();
		ReporteCabecera rc=datos.getCabecera();
		String path="";
		
		try{
			path=ConfiguracionGlobal.pathResources+"/reports_repositorio/"+rc.getCodigoAnalisis()+".pdf";
			List<ReporteDetalle>detAux=new ArrayList<ReporteDetalle>();
			detAux.add(new ReporteDetalle());
			if(detalleList.size()==0) detalleList.add(new ReporteDetalle());
			generarPDFArchivo(reporteResumen,getCabeceraParams(datos),detAux,path);
		}catch(Exception e)
		{
			Log.log(e, Log.MOD_UTILS, Log.LEVEL_ERROR, ReportesManager.class, "Error al generar reporte...");
			return null;
		}
		return path;
		
		
		
    }
	
	
	
    private static Container generarPDFContainer(String subReportFileName, Map<String, Object> parameters, List detalleList)
    {
      Container reporteContainer=null;    	
      try
      {
        //JasperReport subreporte = JasperCompileManager.compileReport(subReportFileName);
        JRBeanCollectionDataSource dataSource= new JRBeanCollectionDataSource(detalleList);
        JasperPrint documento=JasperFillManager.fillReport(subReportFileName,parameters, dataSource);
        JasperViewer jviewer = new JasperViewer(documento, false);
        reporteContainer= jviewer.getContentPane();
      } catch (Exception e) 
      {
         e.printStackTrace();
      }
      return reporteContainer;
    }
    private static void generarPDFArchivo(String subReportFileName, Map<String, Object> parameters, List detalleList, String destFileName )
    {
      try
      {
        //JasperReport subreporte = JasperCompileManager.compileReport(subReportFileName);
        JRBeanCollectionDataSource dataSource= new JRBeanCollectionDataSource(detalleList);
        JasperPrint documento=JasperFillManager.fillReport(subReportFileName,parameters, dataSource);
        JasperExportManager.exportReportToPdfFile(documento, destFileName);
      } catch (Exception e) 
      {
         e.printStackTrace();
      }
      System.out.println("Done filling!!! ...");
    }

	private static Map<String, Object>getCabeceraParams(ReporteData data)
	{
		ReporteCabecera rc=data.getCabecera();
		
		Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("mail", rc.getCorreo());
        parameters.put("fechasolicitud",rc.getFechaSolicitud() );
        parameters.put("fechaanalisis",rc.getFechaAnalisis());
        parameters.put("horasolicitud",rc.getHoraSolicitud() );
        parameters.put("horaanalisis",rc.getHoraAnalisis() );
        parameters.put("algcomparacion",rc.getAlgoritmoComparacion());
        parameters.put("algextraccion",rc.getAlgoritmoExtracion() );
        parameters.put("documento",rc.getDocumento() );
        parameters.put("totalPlagio",rc.getTotalPlagio()+"");
        parameters.put("codigoAnalisis",rc.getCodigoAnalisis());
        parameters.put("SUB_DATA_SOURCE", data.getDetallesComparador());
        parameters.put("SUB_DATA_SOURCE_EXTRACTOR", data.getDetallesExtractor());
        return parameters;
		
	}
	
	public static void concatPDFs(List<InputStream> streamOfPDFFiles,
            OutputStream outputStream, boolean paginate) {
 
        Document document = new Document();
        try {
            List<InputStream> pdfs = streamOfPDFFiles;
            List<PdfReader> readers = new ArrayList<PdfReader>();
            int totalPages = 0;
            Iterator<InputStream> iteratorPDFs = pdfs.iterator();
 
            // Create Readers for the pdfs.
            while (iteratorPDFs.hasNext()) {
                InputStream pdf = iteratorPDFs.next();
                PdfReader pdfReader = new PdfReader(pdf);
                readers.add(pdfReader);
                totalPages += pdfReader.getNumberOfPages();
            }
            // Create a writer for the outputstream
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
 
            document.open();
            BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
                    BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
            // data
 
            PdfImportedPage page;
            int currentPageNumber = 0;
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();
 
            // Loop through the PDF files and add to the output.
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();
 
                // Create a new page in the target for each source page.
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();
                    pageOfCurrentReaderPDF++;
                    currentPageNumber++;
                    page = writer.getImportedPage(pdfReader,
                            pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
 
                    // Code for pagination.
                    if (paginate) {
                        cb.beginText();
                        cb.setFontAndSize(bf, 9);
                        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, ""
                                + currentPageNumber + " of " + totalPages, 520,
                                5, 0);
                        cb.endText();
                    }
                }
                pageOfCurrentReaderPDF = 0;
            }
            outputStream.flush();
            document.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document.isOpen())
                document.close();
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
	
}
